package com.ruoyi.common.utils.baidu;

import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.Map;

@Component
@Slf4j
public class BaiduMapUtils {

    public static String URL = "https://api.map.baidu.com/geoconv/v1/?";

    /**
     * 网页上申请语音识别应用获取的apiKey
     */
    @Value("${baiduMap.appKey}")
    private String apiKey;


//    public String translateWgs84ToBd09(String coords) {
//        return this.translateOthercoordToBdcoord(coords, 1, 5);
//    }

    public double[] translateBd09mcToGcj02(String coords) {
        return this.translateOthercoordToBdcoord(coords, 6, 3);
    }

    /**
     * @param coords 需转换的源坐标，多组坐标以“;”分隔（经度，纬度），注意：一次请求最多支持100个坐标点。
     * @param from   源坐标类型：
     *               1：GPS标准坐标；
     *               2：搜狗地图坐标；
     *               3：火星坐标（gcj02），即高德地图、腾讯地图和MapABC等地图使用的坐标；
     *               4：3中列举的地图坐标对应的墨卡托平面坐标;
     *               5：百度地图采用的经纬度坐标（bd09ll）；
     *               6：百度地图采用的墨卡托平面坐标（bd09mc）;
     *               7：图吧地图坐标；
     *               8：51地图坐标；
     * @param to     目标坐标类型：
     *               3：火星坐标（gcj02），即高德地图、腾讯地图及MapABC等地图使用的坐标；
     *               5：百度地图采用的经纬度坐标（bd09ll）；
     *               6：百度地图采用的墨卡托平面坐标（bd09mc）；
     * @return
     */
    private double[] translateOthercoordToBdcoord(String coords, int from, int to) {
        HttpRequest httpRequest = HttpUtil.createGet("https://api.map.baidu.com/geoconv/v1/");
        UrlBuilder urlBuilder = UrlBuilder.of("https://api.map.baidu.com/geoconv/v1/");
        urlBuilder.addQuery("coords", coords);
        urlBuilder.addQuery("from", from);
        urlBuilder.addQuery("to", to);
        urlBuilder.addQuery("ak", apiKey);
        //urlBuilder示例：urlBuilder: https://api.map.baidu.com/geoconv/v1/?coords=118.991258,29.488069;118.990918,29.488613&from=1&to=5&ak=kH1d85qDzdy976vUrzEGT4a3ggVZu3KK
//        log.info("translateOthercoordToBdcoord urlBuilder: {}", urlBuilder);
        httpRequest.setUrl(urlBuilder);
        HttpResponse httpResponse = httpRequest.execute();
//        log.info("translateOthercoordToBdcoord httpResponse: {}", httpResponse);
        String bodyResult = httpResponse.body();
        //返回结果示例：bodyResult: {"status":0,"result":[{"x":119.00279567042023,"y":29.491233123112314},{"x":119.00245547449843,"y":29.49177141142839}]}
//        log.info("translateOthercoordToBdcoord bodyResult: {}", bodyResult);
        JSONObject jsonObject = JSONObject.parseObject(bodyResult);
        int status = jsonObject.getIntValue("status");
        if (status == 0) { //请求返回成功
            JSONArray result = jsonObject.getJSONArray("result");
            log.info("translateOthercoordToBdcoord result: {}", result);
            double[] coordArr = new double[result.size() * 2];
            for (int i = 0; i < result.size(); i++) {
                JSONObject jsonObject1 = result.getJSONObject(i);
                double lng = (new BigDecimal(jsonObject1.getDouble("x"))).setScale(6, BigDecimal.ROUND_HALF_DOWN).doubleValue();
                double lat = (new BigDecimal(jsonObject1.getDouble("y"))).setScale(6, BigDecimal.ROUND_HALF_DOWN).doubleValue();
                coordArr[2 * i] = lng;
                coordArr[2 * i + 1] = lat;
            }

            log.info("translateOthercoordToBdcoord coordArr: {}", Arrays.toString(coordArr));

            return coordArr;
        } else { //请求返回失败

        }

        return null;
    }

    private String translateOthercoordToBdcoord2(String coords, int from, int to) {
        StringBuffer queryString = new StringBuffer();
        queryString.append(URL);
        queryString.append("coords=" + coords + "&");
        queryString.append("from=" + from + "&");
        queryString.append("to=" + to + "&");
        queryString.append("ak=" + apiKey);

        try {
            java.net.URL url = new URL(queryString.toString());
            URLConnection httpConnection = url.openConnection();
            InputStreamReader isr = new InputStreamReader(httpConnection.getInputStream());
            BufferedReader reader = new BufferedReader(isr);
            StringBuffer buffer = new StringBuffer();
            String line;
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            reader.close();
            isr.close();

            String result = buffer.toString();
            log.info("translateOthercoordToBdcoord result: {}", result);
            return result;
        } catch (Exception e) {
            log.error("translateOthercoordToBdcoord2 e: {}", e.getMessage());
        }

        return "";
    }

    /**
     * 默认ak
     * 选择了ak，使用IP白名单校验：
     * 根据您选择的AK已为您生成调用代码
     * 检测到您当前的ak设置了IP白名单校验
     * 您的IP白名单中的IP非公网IP，请设置为公网IP，否则将请求失败
     * 请在IP地址为xxxxxxx的计算发起请求，否则将请求失败
     */
    public void requestGetAK(Map<String, String> param) {
        if (param == null || param.size() <= 0) {
            return;
        }

        StringBuffer queryString = new StringBuffer();
        queryString.append(URL);
        for (Map.Entry<?, ?> pair : param.entrySet()) {
            queryString.append(pair.getKey() + "=");
            //    第一种方式使用的 jdk 自带的转码方式  第二种方式使用的 spring 的转码方法 两种均可
            //    queryString.append(URLEncoder.encode((String) pair.getValue(), "UTF-8").replace("+", "%20") + "&");
            queryString.append(UriUtils.encode((String) pair.getValue(), "UTF-8") + "&");
        }

        if (queryString.length() > 0) {
            queryString.deleteCharAt(queryString.length() - 1);
        }

        try {
            java.net.URL url = new URL(queryString.toString());
            System.out.println(queryString.toString());
            URLConnection httpConnection = (HttpURLConnection) url.openConnection();
            httpConnection.connect();

            InputStreamReader isr = new InputStreamReader(httpConnection.getInputStream());
            BufferedReader reader = new BufferedReader(isr);
            StringBuffer buffer = new StringBuffer();
            String line;
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            reader.close();
            isr.close();
            log.info("requestGetAK result: {}", buffer.toString());

        } catch (IOException e) {
            log.error("requestGetAK e: {}", e.getMessage());
        }
    }

}
